package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.exception.CustomException;
import com.heima.model.common.admin.dtos.AdChannelDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.pojos.wemedia.WmChannel;
import com.heima.model.common.pojos.wemedia.WmNews;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.service.AdChannelService;
import com.heima.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author 杨尚杰
 * @data 2024/8/1 10:56
 */
@Service
public class AdChannelServiceImpl extends ServiceImpl<WmChannelMapper,WmChannel> implements AdChannelService {

    @Autowired
    private WmChannelMapper wmChannelMapper;
    @Autowired
    private WmNewsService wmNewsService;
    /**
     * 频道分页查询
     *
     * @param channelDto
     * @return
     */
    @Override
    public ResponseResult queryPage(AdChannelDto channelDto) {
        //1.参数校验
        if (channelDto == null)
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        channelDto.checkParam();
        //2.组装条件wrapper
        LambdaQueryWrapper<WmChannel> wrapper = Wrappers.<WmChannel>lambdaQuery();
        //2.1 模块查询频道名称
        if (StringUtils.isNotEmpty(channelDto.getName())) {
            wrapper.like(WmChannel::getName, channelDto.getName());
        }
        //2.2 账号状态
        if (channelDto.getStatus() != null) {
            wrapper.eq(WmChannel::getStatus, channelDto.getStatus());
        }
        //2.3 按创建时间倒序排列
        wrapper.orderByDesc(WmChannel::getCreatedTime);
        //3. 构建分页
        Page<WmChannel> page = new Page<>(channelDto.getPage(), channelDto.getSize());
        //4. 进行分页条件查询
        page(page, wrapper);
        //5. 封装结果返回
        PageResponseResult pr = new PageResponseResult((int)page.getCurrent(),
                (int) page.getSize(), (int) page.getTotal());
        pr.setData(page.getRecords());
        return pr;
    }

    /**
     * 保存频道
     * @param channelDto
     * @return
     */
    @Override
    public ResponseResult saveChannel(AdChannelDto channelDto) {
        //参数校验
        if (channelDto == null)
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        WmChannel wmChannel = new WmChannel();
        BeanUtils.copyProperties(channelDto, wmChannel);
        // 检查频道名称是否已存在
        if (isNameExist(wmChannel.getName())) {
            throw new CustomException(AppHttpCodeEnum.CHANNEL_NAME_EXIST);
        }
        wmChannel.setName(channelDto.getName());
        wmChannel.setDescription(channelDto.getDescription());
        wmChannel.setIsDefault(true); //默认为true
        wmChannel.setStatus(channelDto.getStatus());
        wmChannel.setOrd(channelDto.getOrd());
        wmChannel.setCreatedTime(new Date());
        wmChannelMapper.insert(wmChannel);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 检查频道名称是否已存在
     * @param name
     * @return
     */
    private boolean isNameExist(String name) {
        // 根据频道名称查询频道数量
        List<WmChannel> nameList = wmChannelMapper.selectList(new QueryWrapper<WmChannel>().eq("name", name));
        boolean nameExist = nameList.size() > 0;
        return nameExist;
    }

    /**
     * 判断是否是当前id的频道名称
     * @param id
     * @param name
     * @return
     */
    private boolean isNameExistExcludingCurrent(Integer id, String name) {
        // 构建查询条件：查询除当前id以外的同名频道数量
        QueryWrapper<WmChannel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name).ne("id", id);

        // 执行查询
        List<WmChannel> nameList = wmChannelMapper.selectList(queryWrapper);

        // 如果查询结果不为空，则表示除当前id外存在同名频道，返回true；否则返回false
        return !nameList.isEmpty();
    }

    /**
     * 修改频道
     *
     * @param channelDto
     * @return
     */
    @Override
    public ResponseResult updateChannel(AdChannelDto channelDto) {
        //参数校验
         if (channelDto == null)
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        WmChannel wmChannel = new WmChannel();
        BeanUtils.copyProperties(channelDto, wmChannel);
        //如果频道被引用则不能禁用
        int count = wmNewsService.count(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getChannelId, wmChannel.getId())
                .eq(WmNews::getStatus, WmNews.Status.PUBLISHED.getCode()));
        if(count > 0){
            return ResponseResult.errorResult(AppHttpCodeEnum.CHANNEL_NOT_ENABLE);
        }
        // 检查频道名称是否已存在
        if(channelDto.getName().equals(wmChannel.getName()) &&
                !isNameExistExcludingCurrent(channelDto.getId(),channelDto.getName())){
            // 如果当前频道名称没有变更，并且不存在同名频道（排除当前频道），则不抛出异常
        }else if (isNameExist(wmChannel.getName())){
            throw new CustomException(AppHttpCodeEnum.CHANNEL_NAME_EXIST);
        }
        wmChannel.setCreatedTime(new Date());
        wmChannelMapper.updateById(wmChannel);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除频道
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult delChannel(Integer id) {
        //参数校验
        if(id == null)
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
       WmChannel wmChannel = wmChannelMapper.selectById(id);
        //只有禁用的频道才能删除
        if (wmChannel.getStatus() == true)
        throw new CustomException(AppHttpCodeEnum.CHANNEL_NOT_DELETE);
        wmChannelMapper.deleteById(id);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
